﻿using System;
using System.Diagnostics;
using System.Reactive.Disposables;
using Machine.Specifications;
using RxHeat.Tracing;

namespace RxHeat.Tests.Tracing
{
    [Subject(typeof (IRxHeatTraceListner), "when IRxHeatTraceListner has custom implementation")]
    public class when_custom_IRxHeatTraceListner : EstablishDefaultTracer
    {
        public class when_tracing_empty_message
        {
            private Because of = () =>
                {
                    RxHeat.Tracing.ObservableExtensions.TraceDisposable(null, string.Empty, string.Empty, null);
                    _output.ForEach(x => Debug.WriteLine(x));
                };

            private It should_not_be_empty = () => _output.Count.ShouldBeGreaterThan(0);
        }

        public class when_tracing_null_disposable
        {
            private Because of =
                () =>
                    {
                        RxHeat.Tracing.ObservableExtensions.TraceDisposable(null, "when_tracing_null_disposable",
                                                                            "when_tracing_null_disposable_message", null);
                        _output.ForEach(x => Debug.WriteLine(x));
                    };

            private It should_not_be_empty = () => _output.Count.ShouldBeGreaterThan(0);
        }


        public class when_tracing_with_a_message : TraceOutput
        {
            protected static readonly string _key = Guid.NewGuid().ToString();
            protected static readonly string _message = Guid.NewGuid().ToString();
            protected static readonly Func<string> _messageExec = () => _message;

            protected static readonly IDisposable _disposable =
                Disposable.Create(() => Debug.WriteLine("Disposing the disposable"));

            protected static string _outputEntry = string.Empty;

            private Behaves_like<B_good_disposable_trace_message_specification> A_good_disposable_formated_trace_message;

            private Because of =
                () =>
                    {
                        _disposable.TraceDisposable(_key, _message);
                        _outputEntry = _output.Find(x => x.ToString().Contains(_disposable.GetHashCode().ToString()));
                        _output.ForEach(x => Debug.WriteLine(x));
                    };
        }

        public class when_tracing_with_a_message_function : TraceOutput
        {
            protected static string _key = Guid.NewGuid().ToString();
            protected static string _message = Guid.NewGuid().ToString();
            protected static Func<string> _messageExec = () => _message;
            protected static string _outputEntry = string.Empty;

            protected static readonly IDisposable _disposable =
                Disposable.Create(() => Debug.WriteLine("Disposing the disposable"));

            private Behaves_like<B_good_disposable_trace_message_specification>
                A_good_disposable_trace_message_specification;

            private Because of =
                () =>
                    {
                        _disposable.TraceDisposable(_key, _messageExec);
                        _outputEntry = _output.Find(x => x.ToString().Contains(_disposable.GetHashCode().ToString()));
                        _output.ForEach(x => Debug.WriteLine(x));
                    };
        }
    }
}